package acharOndeMetodoEhChamado;

import hintEmCimaDoMetodo.SingletonArmazenaCabecalhoMetodo;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy;
import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.views.navigator.ResourceNavigator;

import p.EditorAction1Delegate;

public class PegadorDeMetodosQueChamamMetodoEspecifico 
{
	public HashSet<IMethod> getCallersOf(IMethod m) {
		 
		 CallHierarchy callHierarchy = CallHierarchy.getDefault();
		 
		 IMember[] members = {m};
		 
		 MethodWrapper[] methodWrappers = callHierarchy.getCallerRoots(members);
		  HashSet<IMethod> callers = new HashSet<IMethod>();
		  for (MethodWrapper mw : methodWrappers) {
		    MethodWrapper[] mw2 = mw.getCalls(new NullProgressMonitor());
		    HashSet<IMethod> temp = getIMethods(mw2);
		    callers.addAll(temp);    
		   }
		 
		return callers;
		}
		 
		 HashSet<IMethod> getIMethods(MethodWrapper[] methodWrappers) {
		  HashSet<IMethod> c = new HashSet<IMethod>(); 
		  for (MethodWrapper m : methodWrappers) {
		   IMethod im = getIMethodFromMethodWrapper(m);
		   if (im != null) {
		    c.add(im);
		   }
		  }
		  return c;
		 }
		 
		 IMethod getIMethodFromMethodWrapper(MethodWrapper m) {
		  try {
		   IMember im = m.getMember();
		   if (im.getElementType() == IJavaElement.METHOD) {
		    return (IMethod)m.getMember();
		   }
		  } catch (Exception e) {
		   e.printStackTrace();
		  }
		  return null;
		 }

		 
		 
		 static IMethod findMethod(IType type, String methodName) throws JavaModelException
		 {

		     IMethod[] methods = type.getMethods();
		     IMethod theMethod = null;

		     for (int i = 0; i < methods.length; i++)
		     {
		         IMethod imethod = methods[i];
		         if (imethod.getElementName().equals(methodName)) {
		             theMethod = imethod;
		         }
		     }

		     if (theMethod == null)
		     {           
		         System.out.println("Error, method" + methodName + " not found");
		         return null;
		     }

		     return theMethod;
		 }
		 
		 static IMethod findMethodPorCabecalho(IType type, String cabecalhoDoMetodo) throws JavaModelException
		 {

		     IMethod[] methods = type.getMethods();
		     IMethod theMethod = null;

		     for (int i = 0; i < methods.length; i++)
		     {
		         IMethod imethod = methods[i];
		         String sourceDoMetodo = imethod.getSource();
		         String[] sourceDoMetodoDivididoPorChave = sourceDoMetodo.split("{");
		         //so precisaremos de tudo que vem antes da primeira chave
		         String cabecalhoDoMetodoIMethod = sourceDoMetodoDivididoPorChave[0];
		         
		         if (cabecalhoDoMetodoIMethod.compareTo(cabecalhoDoMetodo) == 0) 
		         {
		             theMethod = imethod;
		         }
		     }

		     if (theMethod == null)
		     {           
		         System.out.println("Erro, cabecalho do metodo:" + cabecalhoDoMetodo + " not found");
		         return null;
		     }

		     return theMethod;
		 }
	
		 
	public void metodoPrincipal()
	{
		PegadorDeMetodosQueChamamMetodoEspecifico  callGen = new PegadorDeMetodosQueChamamMetodoEspecifico ();
		ResourcesPlugin.getPlugin().getStateLocation();
		IWorkspace workspace=ResourcesPlugin.getWorkspace();
		//IProject project = workspace.getRoot().getProject("ProjetoFormatacaoBugada");
		
		
		IProject project = pegarProjetoJavaSendoEditado(workspace);
		
		IJavaProject javaProject = JavaCore.create(project);
		System.out.println("javaProject:" + javaProject.getPath().toString());
		
		/*try
		{
			IType type = javaProject.findType("p.ClasseFormBugada");
			String cabecalhoMetodo = SingletonArmazenaCabecalhoMetodo.getInstance().getCabecalhoMetodoSelecionado();
		    IMethod m = findMethodPorCabecalho(type, cabecalhoMetodo);
		    Set<IMethod> methods = new HashSet<IMethod>();
		    methods = callGen.getCallersOf(m);
		    for (Iterator<IMethod> i = methods.iterator(); i.hasNext();)
		    {
		        System.out.println(i.next().toString());
		    }
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}*/
	}
	
	public IProject pegarProjetoJavaSendoEditado(IWorkspace workspace)
	{
		IEditorPart editorPart = 
				PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); 

		String activeProjectName = "";
				if(editorPart != null) 
				{ 
				IFileEditorInput input = (IFileEditorInput)editorPart.getEditorInput() ; 
				IFile file = input.getFile(); 
				IProject activeProject = file.getProject(); 
				activeProjectName = activeProject .getName(); 
				} 
		IProject project = workspace.getRoot().getProject(activeProjectName);
		
		return project;

	}

}
